#ifndef SCOPED_PTR_H_
#define SCOPED_PTR_H_

template <typename T>
class scoped_array {
    public:
        explicit scoped_array(T* t) : t_(t) {}
        ~scoped_array() {
            delete[] t_;
        }

        T* get() { return t_; }
        const T* get() const { return t_; }
        T* release() { T* t = t_; t_ = NULL; return t; }
        void reset(T* t = NULL) { 
            if (t_) delete [] t_;
            t_ = t;
        }

        T& operator[](std::ptrdiff_t i) const {
            return t_[i];
        }

    private:
        T* t_;
};

template <typename T>
class scoped_ptr_malloc {
    public:
        explicit scoped_ptr_malloc(T* t) : t_(t) {}
        ~scoped_ptr_malloc() {
            free(t_);
        }

        T* get() { return t_; }
        const T* get() const { return t_; }
        T* release() { T* t = t_; t_ = NULL; return t; }
        void reset(T* t = NULL) { 
            if (t_) free(t_);
            t_ = t;
        }

    private:
        T* t_;
};

#endif  // SCOPED_PTR_H_
